package com.cxx.purchasecharge.component.controller;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cxx.purchasecharge.component.bean.ActionResult;
import com.cxx.purchasecharge.component.bean.ActionResult.ActionResultStatus;
import com.cxx.purchasecharge.component.bean.BaseBean;
import com.cxx.purchasecharge.component.bean.DataGridRequestForm;
import com.cxx.purchasecharge.component.bean.GoodsTypeBean;
import com.cxx.purchasecharge.component.utils.AjaxUtils;
import com.cxx.purchasecharge.component.utils.ComponentConstants;
import com.cxx.purchasecharge.component.utils.MessageProperties;
import com.cxx.purchasecharge.core.model.persistence.GoodsType;
import com.cxx.purchasecharge.dal.GoodsTypeDao;

@Controller
@RequestMapping ("/goodsType")
public class GoodsTypeManager
{
    private static final Logger logger = Logger.getLogger (GoodsTypeManager.class);

    @Autowired
    private GoodsTypeDao goodsTypeDao;

    @RequestMapping (value = "/")
    public String redirectToGoodsTypeManagement (ModelMap model)
    {
        return "goodsTypeManagement";
    }

    @RequestMapping (value = "/checkExist", method = RequestMethod.POST)
    public @ResponseBody
    String checkExist (@RequestParam String goodsTypeId, @RequestParam String name)
    {
        if (StringUtils.isBlank (goodsTypeId))
        {
            // new
            GoodsType obj = goodsTypeDao.findByName (name);
            if (null != obj)
            {
                return "false";
            }
        }
        else
        {
            // edit
            long id = Long.parseLong (goodsTypeId);
            GoodsType goodsType = goodsTypeDao.findByName (name);
            if (null != goodsType && goodsType.getId () != id)
            {
                return "false";
            }
        }

        return "true";
    }

    @RequestMapping (value = "/getAllType", method = RequestMethod.POST)
    public @ResponseBody
    String getGoodsTypes (DataGridRequestForm dataGridRequestForm)
    {
        List <GoodsType> goodsTypes = (List <GoodsType>) goodsTypeDao.findAll ();
        List <GoodsTypeBean> goodsTypeBeans = new ArrayList <GoodsTypeBean> ();
        if (null != goodsTypes)
        {
            for (GoodsType goodsType : goodsTypes)
            {
                if (null != goodsType && null == goodsType.getParent ())
                {
                    GoodsTypeBean goodsTypeBean = goodsType2GoodsTypeBean (goodsType);
                    goodsTypeBeans.add (goodsTypeBean);
                }
            }
        }
        JSONArray jsonObject = JSONArray.fromObject (goodsTypeBeans);
        return jsonObject.toString ();
    }
    
    @RequestMapping (value = "/asyncGetGoodsType", method = RequestMethod.POST)
    public @ResponseBody
    String asyncGetGoodsType (BaseBean baseBean)
    {
        List <GoodsTypeBean> goodsTypeBeans = new ArrayList <GoodsTypeBean> ();
        if(StringUtils.isBlank (baseBean.getId ())) 
        {
            List <GoodsType> goodsTypes = (List <GoodsType>) goodsTypeDao.findAll ();
            if (null != goodsTypes)
            {
                for (GoodsType goodsType : goodsTypes)
                {
                    if (null != goodsType && null == goodsType.getParent ())
                    {
                        GoodsTypeBean goodsTypeBean = goodsType2GoodsTypeBean (goodsType);
                        goodsTypeBeans.add (goodsTypeBean);
                    }
                }
            }
        }
        else 
        {
            List<GoodsType> goodsTypeList = goodsTypeDao.findByParent (Long.parseLong (baseBean.getId ()));
            if(CollectionUtils.isNotEmpty (goodsTypeList)) 
            {
                for(GoodsType goodsType : goodsTypeList) 
                {
                    goodsTypeBeans.add (goodsType2GoodsTypeBean (goodsType));
                }
            }
        }
        
        JSONArray jsonObject = JSONArray.fromObject (goodsTypeBeans);
        return jsonObject.toString ();
    }

    private GoodsTypeBean goodsType2GoodsTypeBean (GoodsType goodsType)
    {
        GoodsTypeBean goodsTypeBean = new GoodsTypeBean ();
        if (null != goodsType.getParent ())
        {
            goodsTypeBean.setId (goodsType.getId () + "");
            goodsTypeBean.setText (goodsType.getName ());
            goodsTypeBean.setState ("open");
            List <GoodsTypeBean> children = new ArrayList <GoodsTypeBean> ();
            List <GoodsType> list = goodsTypeDao.findByParent (goodsType.getId ());
            if(CollectionUtils.isNotEmpty (list)) 
            {
                for (GoodsType type : list)
                {
                    children.add (goodsType2GoodsTypeBean (type));
                }
            }
            goodsTypeBean.setChildren (children);
        }
        else
        {
            goodsTypeBean.setId (goodsType.getId () + "");
            goodsTypeBean.setText (goodsType.getName ());
            goodsTypeBean.setState ("open");
            List <GoodsTypeBean> children = new ArrayList <GoodsTypeBean> ();
            List <GoodsType> list = goodsTypeDao.findByParent (goodsType.getId ());
            if(CollectionUtils.isNotEmpty (list)) 
            {
                for (GoodsType type : list)
                {
                    children.add (goodsType2GoodsTypeBean (type));
                }
            }
            goodsTypeBean.setChildren (children);
        }
        return goodsTypeBean;
    }
    
    @RequestMapping (value = "/newGoodsType", method = RequestMethod.POST)
    public void addGoodsType (GoodsTypeBean goodsTypeBean, BindingResult bindingResult, HttpServletResponse response)
                                                                                                                     throws Exception
    {
        response.setContentType ("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter ();
        if (bindingResult.hasErrors ())
        {
            logger.error (bindingResult.getAllErrors ());
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            JSONObject jsonObject = JSONObject.fromObject (ar);
            writer.write (jsonObject.toString ());
            // return jsonObject.toString ();
        }
        else
        {
            GoodsType goodsType = new GoodsType (goodsTypeBean.getText ());
            String id = goodsTypeBean.getId ();
            if (null != id && !"".equals (id))
            {
                goodsType.setId (Long.parseLong (id));
            }
            String parentId = goodsTypeBean.getParentId ();
            if (!StringUtils.isBlank (parentId))
            {
                GoodsType parentGoodsType = new GoodsType ();
                parentGoodsType.setId (Long.parseLong (parentId));
                goodsType.setParent (parentGoodsType);
            }

            try
            {
                GoodsType dbGoodsType = goodsTypeDao.save (goodsType);
                JSONObject goodsTypeJson = JSONObject.fromObject (dbGoodsType);
                // return new String(goodsTypeJson.toString ().getBytes(),
                // "ISO-8859-1");
                // return goodsTypeJson.toString ();
                writer.write (goodsTypeJson.toString ());
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ActionResult ar = ActionResult.serverError ()
                                              .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_ADD_FAIL,
                                                                                                    ComponentConstants.MSG_GOODS_TYPE))
                                              .build ();
                JSONObject jsonObject = JSONObject.fromObject (ar);
                // return jsonObject.toString ();
                writer.write (jsonObject.toString ());
            }
        }
    }

    @RequestMapping (value = "/updateGoodsType", method = RequestMethod.POST)
    public void updateGoodsType (GoodsTypeBean goodsTypeBean, BindingResult bindingResult, HttpServletResponse response)
                                                                                                                        throws Exception
    {
        response.setContentType ("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter ();
        if (bindingResult.hasErrors ())
        {
            logger.error (bindingResult.getAllErrors ());
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            JSONObject jsonObject = JSONObject.fromObject (ar);
            writer.print (jsonObject.toString ());
            // return jsonObject.toString ();
        }
        else
        {
            GoodsType goodsType = new GoodsType (goodsTypeBean.getText ());
            String id = goodsTypeBean.getId ();
            if (null != id && !"".equals (id))
            {
                goodsType.setId (Long.parseLong (id));
            }
            String parentId = goodsTypeBean.getParentId ();
            if (!StringUtils.isBlank (parentId))
            {
                GoodsType parentGoodsType = new GoodsType ();
                parentGoodsType.setId (Long.parseLong (parentId));
                goodsType.setParent (parentGoodsType);
            }

            try
            {
                GoodsType dbGoodsType = goodsTypeDao.save (goodsType);
                JSONObject goodsTypeJson = JSONObject.fromObject (dbGoodsType);
                writer.print (goodsTypeJson.toString ());
                // return goodsTypeJson.toString ();
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ActionResult ar = ActionResult.serverError ()
                                              .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_UPDATE_FAIL,
                                                                                                    ComponentConstants.MSG_GOODS_TYPE))
                                              .build ();
                JSONObject jsonObject = JSONObject.fromObject (ar);
                writer.print (jsonObject.toString ());
                // return jsonObject.toString ();
            }
        }
    }

    @Transactional
    @RequestMapping (value = "/delGoodsType", method = RequestMethod.POST)
    public @ResponseBody
    String deleteGoodsType (@RequestParam String ids)
    {
        if (null != ids && ids.trim ().length () > 0)
        {
            ActionResult ar = ActionResult.createActionResult ().build ();
            if (ids.indexOf (";") != -1)
            {
                String[] idArr = ids.split (";");
                List <GoodsType> types = new ArrayList <GoodsType> ();
                GoodsType type;
                for (String typeId : idArr)
                {
                    type = new GoodsType ();
                    type.setId (Long.parseLong (typeId));
                    types.add (type);
                }

                try
                {
                    goodsTypeDao.delete (types);
                    ar = ActionResult.ok ()
                                     .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_SUCCESS,
                                                                                           ComponentConstants.MSG_GOODS_TYPE))
                                     .build ();
                }
                catch (Exception e)
                {
                    logger.error (e.getMessage (), e);
                    ar = ActionResult.serverError ()
                                     .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_FAIL,
                                                                                           ComponentConstants.MSG_GOODS_TYPE))
                                     .build ();
                }
            }
            else
            {
                try
                {
                    goodsTypeDao.delete (Long.parseLong (ids));
                    deleteChildrenType (Long.parseLong (ids));
                    ar = ActionResult.ok ()
                                     .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_SUCCESS,
                                                                                           ComponentConstants.MSG_GOODS_TYPE))
                                     .build ();
                }
                catch (Exception e)
                {
                    logger.error (e.getMessage (), e);
                    ar = ActionResult.serverError ()
                                     .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_FAIL,
                                                                                           ComponentConstants.MSG_GOODS_TYPE))
                                     .build ();
                }
            }
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            logger.error (ActionResultStatus.BAD_REQUEST);
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
    }

    private void deleteChildrenType (long id)
    {
        List <GoodsType> childGoodsTypes = goodsTypeDao.findByParent (id);
        goodsTypeDao.delete (childGoodsTypes);
        for (GoodsType type : childGoodsTypes)
        {
            deleteChildrenType (type.getId ());
        }
    }

}
